/*
 *登录界面项目
 *修改日期--2021.12.04
 *修改内容：  1、设置关于窗体为圆角
 *          2、设置标签、按钮、文本框中的字体颜色
 *          3、设置密码登录界面的控件都是圆角+透明样式
 *
 *修改日期--2021.12.05
 *修改内容： 1、窗体可拖动
 *         2、窗体固定长、宽
*/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "formnew_01.h"
#define min(a,b) ((a)<(b)? (a) :(b)) //频繁使用的短小函数，写成宏定义
#define max(a,b) ((a)>(b)? (a) :(b))
extern Formnew_01 *pmid;//外部定义好的类，调用类指针，可以对其进行操作


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

/*
 * 12.05
 * 针对鼠标移动、按下、释放
 * 扩大、缩小窗口
*/
    edgeMargin = 5;         //设置检测边缘为4
    resizeDir = nodir;      //初始化检测方向为无
    setMouseTracking(true); //开启鼠标追踪
    setMinimumSize(600,510);//设置窗体长、宽

/*
 *  12.04
 *  设置关于窗体为圆角
 *  无框架窗口提示
 *  setWindowFlags：这样过后，我们就不能拖动窗口改变位置，以及拖动边缘改变窗口大小了
 *  this为需要设置圆角的窗口指针
 *  drawRoundedRect：画圆角
 *  ( ，15, 15)为设置圆角大小或范围
*/
    setWindowFlags(Qt::FramelessWindowHint);
    QBitmap bmp(this->size());
    bmp.fill();
    QPainter p(&bmp);
    p.setPen(Qt::NoPen);
    p.setBrush(Qt::black);
    p.drawRoundedRect(bmp.rect(), 15, 15);
    setMask(bmp);


/*
 *  12.04
 *  设置标签、按钮、文本框中的字体颜色
 *  设置密码登录界面的控件都是圆角+透明样式
*/
    QPalette palette;
    palette.setColor(QPalette::Text, QColor(247, 122, 16));
    ui->label->setStyleSheet ("border:2px groove gray;border-radius:10px;padding:2px 4px;"      "color:rgb(110,174,248)");
    ui->label_2->setStyleSheet ("border:2px groove gray;border-radius:10px;padding:2px 4px;"    "color:rgb(110,174,248)");
    ui->lineEdit->setStyleSheet ("border:2px groove gray;border-radius:10px;padding:2px 4px;");
    ui->lineEdit_2->setStyleSheet ("border:2px groove gray;border-radius:10px;padding:2px 4px;");
    ui->lineEdit->setPalette(palette);
    ui->lineEdit_2->setPalette(palette);
    ui->pushButton->setStyleSheet ("border:2px groove gray;border-radius:10px;padding:2px 4px;"     "color:rgb(110,174,248)");
    ui->pushButton_2->setStyleSheet ("border:2px groove gray;border-radius:10px;padding:2px 4px;"   "color:rgb(110,174,248)");
    ui->pushButton_3->setStyleSheet ("border:2px groove gray;border-radius:10px;padding:2px 4px;"   "color:rgb(110,174,248)");


/*
*   一旦构建登录界面，就去检索复选框有无选中
*   【优先，必须放在头部位置】读取文本中的字符信息，对【用户名、密码】【CheckBox复选框】设定初始信息
*/
    initCheckBox();

    //实例化【界面1】对象
    //myMainWindow.ui可以说是mainWindow.ui的子界面
    //在创建了【界面0】登录界面的同时，【界面1】myMainWindow就已经被创建了
    //同时，【界面2】formnew_01也被紧跟着创建完成
    //【界面2】formnew_01也同理可以说是【界面1】myMainWindow的子界面
    this->mwd = new myMainWindow;



    //向pmid中发送当前点击到按键的信号，formnew_01.cpp接收响应
    connect(this, &MainWindow::page0, pmid, &Formnew_01::formnew_01_Receive_the_response);
    //【界面1】的信号，恢复当前【界面0】的操作，formnew_01.cpp接收响应
    connect(this->mwd, &myMainWindow::page1, pmid, &Formnew_01::formnew_01_Receive_the_response);




    //点击【界面0】登录按键
    connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::pushButton_login);
    //点击【界面0】取消登录按键
    connect(ui->pushButton_2, &QPushButton::clicked, this, &MainWindow::pushButton_cancel);
    //点击【界面0】修改密码按键
    connect(ui->pushButton_3, &QPushButton::clicked, this, &MainWindow::pushButton_edit_password);

    ui->lineEdit->setMaxLength(8);//编辑框内容最大长度8   

    //【界面1】的信号，恢复当前【界面0】的操作
    connect(this->mwd, &myMainWindow::back_page2, this, &MainWindow::recover);


}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initCheckBox()
{
    QFile statefile_3("C:\\ios2021\\c++\\state.txt");
    statefile_3.open(QIODevice::ReadOnly);//只读方式打开

    //QByteArray既可以用来存储原始的字节，包括'\0'，也可以用来存储传统的8-bit 的以'\0'结尾的字符串
    //读取全部文本信息
    QByteArray state = statefile_3.readAll();
    //inline const char *QByteArray::constData() const--返回值
    const char * state_char = state.constData();

    if( *state_char == '1')
    {
        ui->checkBox->setChecked(true);//【CheckBox复选框】设为长点
        QFile file("C:\\ios2021\\c++\\save_password.txt");
        file.open(QIODevice::ReadOnly);

        //创建数据流，和file文件关联
        QTextStream out(&file);
        QList<QString> strlist;//Qlist容器，里面都是QString类型

        int i=0;
        while(!out.atEnd())//未到末尾，就循环读取到列表中
        {
            strlist.append(out.readLine());//一行行读取，都拼接到list容器中
            qDebug()<< "验证：" << strlist[i++];
        }

        ui->lineEdit->setText(strlist[0]);
        ui->lineEdit_2->setText(strlist[1]);
    }
}

void MainWindow::pushButton_login()//登录
{
    //登录，先去读取‘save_password.txt’文件
    QFile file_pass("C:\\ios2021\\c++\\save_password.txt");
    file_pass.open(QIODevice::ReadOnly);

    //创建数据流，和file文件关联
    QTextStream out(&file_pass);
    QList<QString> strlist;//Qlist容器，里面都是QString类型
    while( !out.atEnd())
    {
        strlist.append(out.readLine());//把txt文件中的内容按照一行一行的读取到list容器中，方便与行编辑器中的【用户名、密码】比较
    }

    if( ( ui->lineEdit->text() == strlist[0] ) && ( ui->lineEdit_2->text() == strlist[1] ))
    {

        //在输入用户名、密码正确时在保存！！
        if(ui->checkBox->isChecked())
        {
            qDebug() << "点击保存输入的用户名、密码复选框" <<endl;

            if( ( ui->lineEdit->text().isEmpty() ) || ( ui->lineEdit_2->text().isEmpty() ))
            {
                qDebug() << "用户名、密码为空" <<endl;
                //return false;
            }
            else
            {
                QFile * fp = new QFile;
                fp->setFileName("save_password.txt");//设定文件名称
                QDir::setCurrent("C:\\ios2021\\c++\\");//指定文件绝对路径
                bool ok = fp->open(QIODevice::WriteOnly);//以WriteOnly方式打开文件，如果在工程文件下没有该txt文件，那么程序将创建该文件，若存在，则将原文件内容清空，

                if(ok)
                {
                    /*
                     * 第一行：用户名
                     * << endl换行，第二行：密码
                    */
                    QTextStream out(fp);
                    out << ui->lineEdit->text() << endl << ui->lineEdit_2->text();
                    fp->close();
                }

                //保存此时复选框的状态值
                int ref = ui->checkBox->isChecked();
                QFile statefile("C:\\ios2021\\c++\\state.txt");
                statefile.open(QIODevice::WriteOnly);

                QString str = QString::number(ref);
                statefile.write(str.toStdString().c_str());
                statefile.close();

            }
        }
        else//取消勾选checkBox，state.txt中的字符串改为'0'
        {
            qDebug() << "取消保存输入的用户名、密码复选框" <<endl;

            QFile statefile_2("C:\\ios2021\\c++\\state.txt");
            statefile_2.open(QIODevice::WriteOnly);

            QString str = QString::number(0);//转换：数字0->QString->String->字符'0'0
            statefile_2.write(str.toStdString().c_str());//转换成字符串形式写进文件
            statefile_2.close();

        }


        QMessageBox *pmess = new QMessageBox(QMessageBox::Information, "提示框", "登录成功,并进行记录 ", \
                                             QMessageBox::Ok);
        pmess->exec();//调用一下消息阻塞

        //密码、用户名都对，隐藏1界面，打开2界面
        this->hide();
        this->mwd->show();

        //===================BBB=============
        emit this->mwd->page1(TRAM_Login, NULL);//发送【登录】信号

    }
    else
    {
        QMessageBox *pmess = new QMessageBox(QMessageBox::Warning, "提示框", "登录失败，请重新输入", \
                                             QMessageBox::Yes);
        pmess->exec();//调用一下消息阻塞
        ui->lineEdit->setFocus(); //将焦点移动到账号输入框
    }


}

void MainWindow::pushButton_cancel()
{
    QMessageBox *pmess = new QMessageBox(QMessageBox::Warning, "提示框", "取消登录", \
                                         QMessageBox::Ok);
    pmess->exec();//调用一下消息阻塞
    QApplication::exit(0);//退出登录
}

void MainWindow::pushButton_edit_password()//修改【用户名、密码】
{
    QFile * fp_edit = new QFile;
    fp_edit->setFileName("save_password.txt");//设定文件名称
    QDir::setCurrent("C:\\ios2021\\c++\\");//指定文件绝对路径
    bool ok = fp_edit->open(QIODevice::WriteOnly);//以WriteOnly方式打开文件，如果在工程文件下没有该txt文件，那么程序将创建该文件，若存在，则将原文件内容清空，

    if(ok)
    {
        //换行，第一行：用户名
        //换行，第二行：密码
        QTextStream out(fp_edit);
        out << ui->lineEdit->text() << endl << ui->lineEdit_2->text();
        QMessageBox *pmess = new QMessageBox(QMessageBox::Warning, "提示框", "修改成功！", \
                                             QMessageBox::Ok);
        pmess->exec();//调用一下消息阻塞
        fp_edit->close();
    }
}

void MainWindow::recover()
{
    //mymainwindow.cpp->mainwindow.cpp的信号响应
    qDebug() << "隐藏【界面1】，打开【界面0】" << endl;
    //隐藏【界面1】，打开【界面0】
    this->mwd->hide();
    this->show();


    //============AAA=============
    emit this->page0(TRAM_Hide_mymainwindow, NULL);


}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "mousePressEvent" <<endl;

    /*
     * 事件触发点相对于桌面的位置；
     * 若鼠标在程序窗口中点击，则通过event->globalPos()获取鼠标在桌面坐标系统的位置
     * 当执行event->ignore()时，意味着这次的事件“我”不要接受他，函数执行完把event给我的父窗口，他会需要的。
    */

    event->ignore();
    if (event->button() == Qt::LeftButton)  //每当按下鼠标左键就记录一下位置
     {
       dragPosition = event->globalPos() - frameGeometry().topLeft();  //获得鼠标按键位置相对窗口左上面的位置

    }
}

void MainWindow::testEdge()
{
     qDebug() << "testEdge" <<endl;
     int diffLeft = abs(cursor().pos().x() - frameGeometry().left());       //计算鼠标距离窗口上下左右有多少距离
     int diffRight = abs(cursor().pos().x() - frameGeometry().right());
     int diffTop = abs(cursor().pos().y() - frameGeometry().top());
     int diffBottom = abs(cursor().pos().y() - frameGeometry().bottom());
     qDebug()<< "左：" << diffLeft << "右：" << diffRight << "上："<< diffTop << "下："<< diffBottom;


     QCursor tempCursor;                                                    //获得当前鼠标样式，注意:只能获得当前鼠标样式然后再重新设置鼠标样式
     tempCursor = cursor();                                                 //因为获得的不是鼠标指针，所以不能这样用:cursor().setXXXXX

     if(diffTop < edgeMargin){                                              //根据 边缘距离 分类改变尺寸的方向
         if(diffLeft < edgeMargin){
             resizeDir = topLeft;
             tempCursor.setShape(Qt::SizeFDiagCursor);
         }
         else if(diffRight < edgeMargin){
             resizeDir = topRight;
             tempCursor.setShape(Qt::SizeBDiagCursor);
         }
         else{
             resizeDir = top;
             tempCursor.setShape(Qt::SizeVerCursor);
         }
     }
     else if(diffBottom < edgeMargin){
         if(diffLeft < edgeMargin){
             resizeDir = bottomLeft;
             tempCursor.setShape(Qt::SizeBDiagCursor);
         }
         else if(diffRight < edgeMargin){
             resizeDir = bottomRight;
             tempCursor.setShape(Qt::SizeFDiagCursor);
         }
         else{
             resizeDir = bottom;
             tempCursor.setShape(Qt::SizeVerCursor);
         }
     }
     else if(diffLeft < edgeMargin){
         resizeDir = left;
         tempCursor.setShape(Qt::SizeHorCursor);
     }
     else if(diffRight < edgeMargin){
         resizeDir = right;
         tempCursor.setShape(Qt::SizeHorCursor);
     }
     else{
         resizeDir = nodir;
         tempCursor.setShape(Qt::ArrowCursor);
     }

     setCursor(tempCursor);                    //重新设置鼠标,主要是改样式


}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "mouseMoveEvent" <<endl;

    event->ignore();
    if (event->buttons() & Qt::LeftButton)
    {                 //如果左键是按下的
      if(resizeDir == nodir){                             //如果鼠标不是放在边缘那么说明这是在拖动窗口
         move(event->globalPos() - dragPosition);
      }
      else{
          int ptop,pbottom,pleft,pright;                   //窗口上下左右的值
          ptop = frameGeometry().top();
          pbottom = frameGeometry().bottom();
          pleft = frameGeometry().left();
          pright = frameGeometry().right();
          if(resizeDir & top){                               //检测更改尺寸方向中包含的上下左右分量
              if(height() == minimumHeight()){
                  ptop = min(event->globalY(),ptop);
              }
              else if(height() == maximumHeight()){
                  ptop = max(event->globalY(),ptop);
              }
              else{
                  ptop = event->globalY();
              }
          }
          else if(resizeDir & bottom){
              if(height() == minimumHeight()){
                  pbottom = max(event->globalY(),ptop);
              }
              else if(height() == maximumHeight()){
                  pbottom = min(event->globalY(),ptop);
              }
              else{
                  pbottom = event->globalY();
              }
          }

          if(resizeDir & left){                        //检测左右分量
              if(width() == minimumWidth()){
                  pleft = min(event->globalX(),pleft);
              }
              else if(width() == maximumWidth()){
                  pleft = max(event->globalX(),pleft);
              }
              else{
                  pleft = event->globalX();
              }
          }
          else if(resizeDir & right){
              if(width() == minimumWidth()){
                  pright = max(event->globalX(),pright);
              }
              else if(width() == maximumWidth()){
                  pright = min(event->globalX(),pright);
              }
              else{
                  pright = event->globalX();
              }
          }
          //从屏幕上（pleft,ptop）位置开始（即为最左上角的点），显示一个[pright*pbottom]的界面（宽--pright，高--pbottom）
          setGeometry(QRect(QPoint(pleft,ptop),QPoint(pright,pbottom)));
      }
  }
  else
  {
    testEdge();   //当不拖动窗口、不改变窗口大小尺寸的时候  检测鼠标边缘

  }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    qDebug() << "mouseReleaseEvent" <<endl;

    event->ignore();
     if(resizeDir != nodir){         //还原鼠标样式
         testEdge();
     }
}

